package main

import (
	"bufio"
	"fmt"
	"os"
	"runtime/pprof"
	"strings"
)

const (
	tagClean = "Exit Undo Redo\n"
	tagDirty = "Put Exit Undo Redo\n"
)

var commands = map[string]func(){

	"Put": func() {
		// update currentfile
		tagstr := mainwin.tag.Contents()[0]
		if len(tagstr) > 0 && tagstr[0] != ' ' {
			currentfile = strings.Fields(tagstr)[0]
		}
		if currentfile == "" {
			fmt.Fprintln(os.Stderr, "no file name")
			return
		}

		f, err := os.Create(currentfile)
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error writing to file:", err)
			return
		}
		defer f.Close()
		fbuf := bufio.NewWriter(f)
		contents := mainwin.edit.Contents()
		for i, l := range contents {
			if i < len(contents)-1 {
				fbuf.Write([]byte(l + "\n"))
			} else {
				fbuf.Write([]byte(l))
			}
		}
		fbuf.Flush()
		mainwin.dirty = false
		updatetag()
	},

	"Exit": func() {
		if *cpuprofile != "" {
			pprof.StopCPUProfile()
		}
		os.Exit(0)
	},

	"Undo": func() {
		mainwin.edit.Undo()
		mainwin.dirty = false
		updatetag()
	},

	"Redo": func() {
		mainwin.edit.Redo()
		mainwin.dirty = false
		updatetag()
	},
}

// populates the tag with commands, depending on the state of the edit buffer
func updatetag() {
	olddot := mainwin.tag.Dot
	// preserve text after the first occurance of "|"
	oldtagstr := strings.Join(mainwin.tag.Contents(), "\n")
	var usertag string
	i := strings.Index(oldtagstr, "|")
	if i > 0 {
		usertag = oldtagstr[i+1 : len(oldtagstr)]
	} else {
		usertag = " "
	}

	tagstr := currentfile + " "
	if mainwin.edit.CanUndo() || mainwin.dirty {
		tagstr += "Undo "
	}
	if mainwin.edit.CanRedo() {
		tagstr += "Redo "
	}
	if mainwin.dirty {
		tagstr += "Put "
	}
	tagstr += "Exit |"
	newi := len(tagstr) - 1
	tagstr += usertag
	if tagstr == oldtagstr {
		// Oops, nothing changed. Bail.
		return
	}
	addr := mainwin.tag.LoadString(tagstr)
	if olddot.Left.Y > 0 {
		mainwin.tag.Select(olddot)
	} else if olddot.Left.X > i {
		olddot.Left.X += newi - i
		if olddot.Right.Y == 0 {
			olddot.Right.X += newi - i
		}
		mainwin.tag.Select(olddot)
	} else {
		addr.Left = addr.Right
		mainwin.tag.Select(addr)
	}
}
